package com.lz.comm.net

import chen.you.comm.log.LogHeaders
import chen.you.comm.log.LogUtils
import com.lz.library.extension.stackString
import okhttp3.FormBody
import okhttp3.Request
import okhttp3.Response
import java.nio.charset.Charset
import java.util.concurrent.TimeUnit

/**
 *  author: you : 2020/09/9
 *  本地日志过滤
 */
internal class HttpLogInterceptor(private val isOnLine: Boolean) {

    /**
     * 请求前的日志处理
     * @return 返回日志开关
     */
    fun onRequest(request: Request, builder: Request.Builder): Boolean {
        val headers = request.headers()
        val printAll = !headers[LogHeaders.LOG_HEADER_ALL]?.also { builder.removeHeader(LogHeaders.LOG_HEADER_ALL) }.isNullOrEmpty()
        val printOffLine = !headers[LogHeaders.LOG_HEADER_OFFLINE]?.also { builder.removeHeader(LogHeaders.LOG_HEADER_OFFLINE) }.isNullOrEmpty()
        val printLogSwitch = if (printOffLine) !isOnLine else printAll

        if (printLogSwitch) {
            val logStr = StringBuilder("--> ${request.url()} ${request.method()}")
            if (headers.size() > 0) {
                logStr.append("\nrequest Headers --> ")
                for (i in 0 until headers.size()) {
                    logStr.append("${headers.name(i)} : ${headers.value(i)} \t")
                }
                logStr.delete(logStr.length - 1, logStr.length)
            }
            if ("POST" == request.method()) {
                val body = request.body()
                if ((body is FormBody) && (body.size() > 0)) {
                    logStr.append("\nPost body --> ")
                    for (i in 0 until body.size()) {
                        logStr.append("${body.encodedName(i)}=${body.encodedValue(i)}&")
                    }
                    logStr.delete(logStr.length - 1, logStr.length)
                }
            }
            LogUtils.i(TAG, logStr.toString())
        }
        return printLogSwitch
    }

    fun onResponse(response: Response, requestTime: Long) {
        val tookMs: Long = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - requestTime)
        val logStr = StringBuilder("<-- ${response.request().url()} ${response.code()} (${tookMs}ms)  --END HTTP ")
        response.body()?.takeIf { it.contentLength() != 0L }?.apply {
            val buffer = source().also { it.request(Long.MAX_VALUE) }.buffer
            logStr.append("\nresponse--> ").append(buffer.clone().readString(UTF8))
        }
        LogUtils.i(TAG, logStr.toString())
    }

    fun onError(request: Request, e: Exception) {
        LogUtils.w(TAG, "<-- ${request.url()}  HTTP FAILED: ${e.stackString()}")
    }

    companion object {
        private val UTF8 = Charset.forName("UTF-8")
        private const val TAG = "HttpLogInterceptor"
    }
}